package com.hwtx.soa.registry.impl;

import com.hwtx.soa.registry.ZkClient;
import com.hwtx.soa.registry.path.DubboPath;
import com.hwtx.soa.registry.path.Path;
import com.hzgj.bcl.soa.config.RegistryDef;
import com.hzgj.bcl.soa.registry.Registry;
import com.hzgj.bcl.soa.registry.RegistryFactory;
import com.hzgj.bcl.soa.registry.RegistryUpdater;
import com.hzgj.bcl.soa.util.Constants;
import com.hzgj.bcl.soa.util.ServiceLoaderUtil;

import java.util.Iterator;

public class ZkRegistryFactory implements RegistryFactory {
    private Registry registry = null;
    private RegistryUpdater registryUpdater = null;
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    @Override
    public Registry getRegistry(RegistryDef registryDef) {
        if (registry == null) {
            synchronized (lock1) {
                if (registry == null) {
                    registry = new ZkRegistry(getClient(registryDef), getPath(registryDef));
                }
            }
        }
        if (registry == null) {
            throw new RuntimeException("can't find any registry of " + registryDef);
        }
        return registry;
    }

    @Override
    public RegistryUpdater getRegistryUpdater(RegistryDef registryDef) {
        if (registryUpdater == null) {
            synchronized (lock2) {
                if (registryUpdater == null) {
                    registryUpdater = new ZkRegistryUpdater(getClient(registryDef), getPath(registryDef));
                }
            }
        }
        return registryUpdater;
    }

    @Override
    public String getName() {
        return Constants.ZK_REGISTRY;
    }


    private ZkClient getClient(RegistryDef registryDef) {
        return new ZkClientImpl(registryDef.getAddress());
    }

    public Path getPath(RegistryDef registryDef) {
        Iterator<Path> iterator = ServiceLoaderUtil.getServiceLoaderObjects(Path.class);
        while (iterator.hasNext()) {
            Path _path = iterator.next();
            if (_path.getName().equalsIgnoreCase(registryDef.getType())) {
                return _path;
            }
        }
        return new DubboPath();
    }
}
